package com.codeyang.advice;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.AuthenticationException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
 * 描述:
 * 做异常处理
 * 这是服务端响应出去的最后一道屏障
 * 避免内行人抓包 发现你的bug 攻击你
 * <p>
 * 我们拿到日志以后  我们可以记录下来
 * 我们可以单独搭建一个log-service模块  和es关联   通过mq写 （异步的）
 * @author CodeYang_Site
 * @version 2021/5/28 21:38
 */
@Slf4j
@RestControllerAdvice
public class WebLogError {


    /**
     * 处理全局运行时异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = RuntimeException.class)
    public ResponseEntity<String> runTimeEx(RuntimeException e) {
        String message = e.getMessage();
        e.printStackTrace();
        log.error("运行时异常" + message);
        return ResponseEntity.ok("服务器维护中，请稍后尝试");
    }

    /**
     * 处理非法参数时异常的方法
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = IllegalArgumentException.class)
    public ResponseEntity<String> illegalEx(IllegalArgumentException e) {
        String message = e.getMessage();
        log.error("非法参数时异常" + message);
        return ResponseEntity.ok(message);
    }


    /**
     * 处理认证时异常|security
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = AuthenticationException.class)
    public ResponseEntity<String> authEx(IllegalArgumentException e) {
        String message = e.getMessage();
        log.error("认证异常" + message);
        return ResponseEntity.ok("登录异常，请重新登录");
    }


    /**
     * 方法参数校验异常
     * @return
     */
    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    public ResponseEntity<String> methodArgumentNotValidException(MethodArgumentNotValidException bindException) {
        //1.获得绑定的返回信息
        BindingResult bindingResult = bindException.getBindingResult();
        //2.获取异常的所有字段
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        StringBuilder msg = new StringBuilder("数据校验失败,原因是:");
        for (FieldError fieldError : fieldErrors) {
            msg.append("Filed:" + fieldError.getField() + ":" + fieldError.getDefaultMessage() + "!");
        }
        return ResponseEntity.badRequest().body(msg.toString());
    }
}
